package com.learning.springboot.springdataJpa.customJpa;

import org.springframework.data.jpa.repository.support.JpaRepositoryFactory;
import org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean;
import org.springframework.data.jpa.repository.support.SimpleJpaRepository;
import org.springframework.data.repository.Repository;
import org.springframework.data.repository.core.RepositoryInformation;
import org.springframework.data.repository.core.RepositoryMetadata;
import org.springframework.data.repository.core.support.RepositoryFactorySupport;
import javax.persistence.EntityManager;
import java.io.Serializable;

/**
 * Created by td on 2017/9/29.
 */
// 自定义RepositoryFactoryBean ，继承JpaRepositoryFacotryBean
public class CustomRepositoryFactoryBean<T extends Repository<S,ID>,S,ID extends Serializable>
        extends JpaRepositoryFactoryBean<T,S,ID> {

    public CustomRepositoryFactoryBean(Class<? extends T> repositoryInterface) {
        super(repositoryInterface);
    }

    // 重写createRepositoryFacory方法, 用当前的CustomRepositoryFactory 创建实例
    @Override
    protected RepositoryFactorySupport createRepositoryFactory(EntityManager entityManager) {

       // return new
        return new CustomRepositoryFactory(entityManager);
    }


    // 创建自定义RepositoryFactory
    private static class CustomRepositoryFactory extends JpaRepositoryFactory {

        public CustomRepositoryFactory(EntityManager entityManager) {
            super(entityManager);
        }

         // 重写getTargetRepository ,获得当前自定义的Repository实现
        @Override
        protected <T, ID extends Serializable> SimpleJpaRepository<?, ?>
        getTargetRepository(RepositoryInformation information, EntityManager entityManager) {

          //  return super.getTargetRepository(information, entityManager);
            return  new CustomReposirotyImpl<T,ID>((Class<T>)information.getDomainType(),entityManager);
        }

        // 重写getRepositoryBaseClass ,获得当前自定义的Repository实现的类型
        @Override
        protected Class<?> getRepositoryBaseClass(RepositoryMetadata metadata) {
            return CustomReposirotyImpl.class;
        }
    }
}

